package com.panfeng.xcloud.im.util;

import net.sf.json.JSONObject;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtilsBean;

import java.beans.PropertyDescriptor;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>Title: NetUtil</p>
 * <p>Description: http工具类</p>
 * <p>Author: xiaobo</p>
 */
public class NetUtil {
    private static final int BUFFER = 3 * 1024 * 1024;
    private static final int CONNECT_TIMEOUT = 36000;
    private static final int READ_TIMEOUT = 30000;
    private static final String CHARSET = "UTF-8";

    /**
     * 获取网络资源流
     */
    public static InputStream getNetResource(String urlStr) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
        httpUrlConnection.connect();
        return httpUrlConnection.getInputStream();
    }

    /**
     * 获取网络资源字节
     */
    public static byte[] getNetByte(String urlStr) throws Exception {
        InputStream is = getNetResource(urlStr);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = is.read(buffer, 0, buffer.length)) > 0) {
            baos.write(buffer, 0, len);
        }
        return baos.toByteArray();
    }

    public static HttpURLConnection getHttpURLConnection(String urlStr,String token,String cookie,boolean isJsonRequest) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
        httpUrlConnection.setConnectTimeout(CONNECT_TIMEOUT);
        httpUrlConnection.setReadTimeout(READ_TIMEOUT);
        httpUrlConnection.setDoInput(true);
        httpUrlConnection.setDoOutput(true);
        httpUrlConnection.setUseCaches(false);
        httpUrlConnection.setRequestProperty("Authorization",token);
        httpUrlConnection.setRequestProperty("Cookie",cookie);
        if(isJsonRequest) {
            httpUrlConnection.setRequestProperty("Content-Type", "application/json");
        }
        httpUrlConnection.connect();
        return httpUrlConnection;
    }

    public static String disconnectHttpURLConnection(HttpURLConnection httpURLConnection,String urlStr,String params) throws Exception {
        OutputStream os = httpURLConnection.getOutputStream();
        os.write(params.getBytes(CHARSET));
        os.flush();
        os.close();

        InputStream is = httpURLConnection.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is),BUFFER);

        String response = null;
        if (httpURLConnection.getResponseCode() == 200) {
            String str = null;
            StringBuilder sb = new StringBuilder();
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            response = sb.toString();
        }

        br.close();
        httpURLConnection.disconnect();

        System.err.println(urlStr);
        System.err.println(params);
        System.err.println(response);

        return response;
    }

    public static String requestJson(String urlStr, String jsonParams) throws Exception {
        return requestJson(urlStr,jsonParams,null,null);
    }

    public static String requestJson(String urlStr, String jsonParams,String token,String cookie) throws Exception {
        HttpURLConnection httpURLConnection = getHttpURLConnection(urlStr,token,cookie,true);
        return disconnectHttpURLConnection(httpURLConnection,urlStr,jsonParams);
    }

    public static String requestFormData(String urlStr, Map<String,Object> formDataMapParams) throws Exception {
        return requestFormData(urlStr,formDataMapParams,null,null);
    }

    public static String requestFormData(String urlStr, String formDataParams) throws Exception {
        return requestFormData(urlStr,formDataParams,null,null);
    }

    public static String requestFormData(String urlStr, String formDataParams,String token,String cookie) throws Exception {
        HttpURLConnection httpURLConnection = getHttpURLConnection(urlStr,token,cookie,false);
        return disconnectHttpURLConnection(httpURLConnection,urlStr,formDataParams);
    }

    public static String requestFormData(String urlStr, Map<String,Object> formDataMapParams,String token,String cookie) throws Exception {
        HttpURLConnection httpURLConnection = getHttpURLConnection(urlStr,token,cookie,false);
        return disconnectHttpURLConnection(httpURLConnection,urlStr,mapToParams(formDataMapParams));
    }

    public static String mapToJson(Map<String,Object> map){
        return JSONObject.fromObject(map).toString();
    }

    public static String mapToParams(Map<String,Object> map){
        return mapToParams(map,new StringBuilder());
    }

    public static String mapToUrlParams(Map<String,Object> map){
        return mapToParams(map,new StringBuilder("?"));
    }

    public static String mapToParams(Map<String,Object> map,StringBuilder sb){
        int size = map.size();
        for(Map.Entry<String,Object> entry : map.entrySet()) {
            size--;
            sb.append(entry.getKey()).append("=").append(entry.getValue());
            if(size!=0){
                sb.append("&");
            }
        }
        return sb.toString();
    }

    public static Map<String, Object> beanToMap(Object obj) throws Exception{
        Map<String, Object> map = new HashMap<String, Object>(0);
        PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
        PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(obj);
        for (int i = 0; i < descriptors.length; i++) {
            String name = descriptors[i].getName();
            if (!"class".equals(name)) {
                map.put(name, propertyUtilsBean.getNestedProperty(obj, name));
            }
        }
        return map;
    }

    public static  <T> T  mapToBean(Map<String,Object> map,Class<T> clazz) throws Exception{
        T bean = clazz.newInstance();
        BeanUtils.populate(bean, map);
        return bean;
    }


}
